home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Toolbox
/
Visual Basic Toolbox (P.I.E.)(1996).ISO
/
compress
/
cxe103
/
cxf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-03
|
7KB
|
254 lines
/*
Copyright (c) 1990-1992 Eugene Nelson
This program demonstrates the suggested usage of the Cx Data Compression
Library. It will compress and decompress a file of any size, containing
any type of data. The compressed data is stored with 16 bit CRC's to
help in detecting errors. It stores the file as blocks of data which
have the following form:
BLOCK
----------------------------------------------------
2 bytes - size of uncompressed block (USIZE)
2 bytes - size of compressed block (CSIZE)
2 bytes - 16 bit CRC (CRC)
CSIZE - data (DATA)
----------------------------------------------------
If a block cannot be compressed, the original data is stored, and
USIZE and CSIZE will be the same. The CRC is computed on the
compressed data.
2 bytes of 0 are stored at the end of the compressed file to indicate
the end of file.
*/
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "cx.h"
/*-------------------------------------------------------------------------*/
void USAGE(void)
{
printf("usage: cxf 1|2|3|t|d infile outfile\n");
printf(" 1|2|3 - compress infile to outfile using method 1,2 or 3\n");
printf(" d - decompress infile to outfile\n");
printf(" t - test integrity of infile\n\n");
printf(" Examples:\n");
printf(" cxf 1 cxf.exe x.x\n");
printf(" cxf t x.x\n");
printf(" cxf d x.x y.y\n");
exit (0);
}
/*-------------------------------------------------------------------------*/
void QUIT(char *s)
{
printf("\n%s\n", s);
exit (0);
}
/*-------------------------------------------------------------------------*/
#define MALLOC(p,n) {if ((p = malloc(n)) == NULL) QUIT ("insufficient memory");}
#define FREE(p) free(p)
#define CREATE(s) open(s, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)
#define OPEN(s) open(s, O_RDWR|O_BINARY, 0)
#define WRITE(f,b,n) {if (write(f, b, n) != n) QUIT ("could not write");}
#define READ(f,b,n) {if (read(f, b, n) != n) QUIT ("could not read");}
#define CLOSE(f) {if (close(f) != 0) QUIT ("could not close");}
/*-------------------------------------------------------------------------*/
void file_compress(char *dst, char *src, CXINT method, CXINT size)
{
int ifile, ofile;
long ifilesize, ofilesize;
CXINT j, k, crc;
CXBUFF ibuff, obuff, tbuff;
if ((ifile = OPEN(src)) == -1)
QUIT ("could not open ifile");
unlink(dst);
if ((ofile = CREATE(dst)) == -1)
QUIT ("could not open ofile");
MALLOC(ibuff, size);
MALLOC(obuff, size+CX_SLOP);
MALLOC(tbuff, CX_C_MAXTEMP);
ifilesize = ofilesize = 0;
while (1)
{
printf(".");
j = read(ifile, ibuff, size);
WRITE(ofile, &j, CXINTSIZE);
ifilesize += j;
ofilesize += CXINTSIZE;
if (j == 0)
break;
k = CX_COMPRESS(method, obuff, size, ibuff, j, tbuff, CX_C_MAXTEMP);
switch (k)
{
case CX_ERR_METHOD:
QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
case CX_ERR_BUFFSIZE:
QUIT("invallid input or output buffer size");
case CX_ERR_TEMPSIZE:
QUIT("invalid temporary buffer size");
}
WRITE(ofile, &k, CXINTSIZE);
if (k == j) /* if block could not be compressed */
{
crc = CX_CRC(ibuff, k);
WRITE(ofile, &crc, sizeof(crc));
WRITE(ofile, ibuff, k)
}
else
{
crc = CX_CRC(obuff, k);
WRITE(ofile, &crc, sizeof(crc));
WRITE(ofile, obuff, k)
}
ofilesize += CXINTSIZE+sizeof(crc)+k;
}
FREE(ibuff);
FREE(obuff);
FREE(tbuff);
CLOSE(ifile);
CLOSE(ofile);
printf("\n");
printf("Insize: %10ld\n", ifilesize);
printf("Outsize: %10ld\n", ofilesize);
if (ifilesize != 0)
printf("Percent: %10d", (ofilesize*100)/ifilesize);
}
/*-------------------------------------------------------------------------*/
void file_decompress(char *dst, char *src)
{
int ifile, ofile;
CXINT j, k, crc;
CXBUFF ibuff, obuff, tbuff;
if ((ifile = OPEN(src)) == -1)
QUIT ("could not open ifile");
if (dst != NULL)
{
unlink(dst);
if ((ofile = CREATE(dst)) == -1)
QUIT ("could not open ofile");
}
MALLOC(ibuff, CX_MAX_BUFFER+CX_SLOP);
MALLOC(obuff, CX_MAX_BUFFER);
MALLOC(tbuff, CX_D_MINTEMP);
while (1)
{
printf(".");
READ(ifile, &j, CXINTSIZE);
if (j == 0)
break;
READ(ifile, &k, CXINTSIZE);
READ(ifile, &crc, sizeof(crc));
READ(ifile, ibuff, k);
if (CX_CRC(ibuff, k) != crc)
QUIT ("CRC error");
if (j == k) /* if block is not compressed */
{
if (dst != NULL)
WRITE(ofile, ibuff, j);
}
else
{
k = CX_DECOMPRESS(obuff, CX_MAX_BUFFER, ibuff, k, tbuff, CX_D_MINTEMP);
switch (k)
{
case CX_ERR_INVALID:
QUIT("data being compressed is corrupt, or was not compressed with Cx.");
case CX_ERR_METHOD:
QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
case CX_ERR_BUFFSIZE:
QUIT("End of Data symbol not found");
case CX_ERR_TEMPSIZE:
QUIT("invalid temporary buffer size");
}
if (k != j)
QUIT("data being compressed is corrupt, or was not compressed with Cx.");
if (dst != NULL)
WRITE(ofile, obuff, j);
}
}
FREE(ibuff);
FREE(obuff);
FREE(tbuff);
CLOSE(ifile);
if (dst != NULL)
CLOSE(ofile);
}
/*-------------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
int ch;
if (argc < 4)
{
if (argc < 3)
USAGE();
ch = toupper(argv[1][0]);
if (ch == 'T')
file_decompress(NULL, argv[2]);
else if (ch == 'R')
file_decompress(NULL, argv[2]);
else
USAGE();
}
else
{
ch = toupper(argv[1][0]);
if (ch == '1')
file_compress(argv[3], argv[2], CX_METHOD1, CX_MAX_BUFFER);
else if (ch == '2')
file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
else if (ch == '3')
file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
else if (ch == 'D')
file_decompress(argv[3], argv[2]);
else
USAGE();
}
QUIT ("Ok");
}